<template>
  <div>
    <el-form :model="formData" :inline="modelValue.inline" :label-position="modelValue.labelPosition" label-suffix=":"
      :rules="rules" :label-width="modelValue.labelWidth" ref="baseForm">
      <!-- 搜索项容器 -->
      <div class="search-items" :class="{ 'auto-fit': modelValue.autoFit }"
        :style="modelValue.autoFit ? {} : { flexWrap: 'wrap' }">
        <!-- <input type="hidden" name="test" value="123" /> -->
        <!-- 动态生成搜索项 -->

        <template v-for="(item, index) in finallyColumns" :key="index">
          <div v-if="item.type === FORM_FIELD_TYPE.TITLE" class="expand-column"
            style="margin-left: 30px; margin-bottom: 20px;">{{ item.title }}</div>
          <el-divider v-if="item.divider" content-position="left" class="expand-column divider-title">{{ item.divider
          }}</el-divider>
          <el-form-item :prop="item.field" :label="item.label" v-else
            :label-width="item.labelWidth || modelValue.labelWidth || '100px'"
            :class="['form-item', item.expandColumn ? 'expand-column' : '']">

            <component v-if="!item.type && item.render && formData"
              :is="item.render({ item, value: formData[item.field], row: formData, handlers })"
              v-model="formData[item.field]" />
            <template v-else-if="item.type === FORM_FIELD_TYPE.INPUT && item.labelField">
              <el-input v-show="false" :style="getColumnWidth(item)" v-model="formData[item.field]" v-bind="item.props"
                :placeholder="item.placeholder" :type="item?.type === 'textarea' ? 'textarea' : 'text'"
                :disabled="item.config?.disabled || false" />

              <el-input :style="getColumnWidth(item)" v-model="formData[item.labelField]" v-bind="item.props"
                :placeholder="item.placeholder" :type="item?.type === 'textarea' ? 'textarea' : 'text'"
                @click="formItemClick(item)" :disabled="item.config?.disabled || false" />
            </template>

            <template v-else-if="item.type === FORM_FIELD_TYPE.CITY_SELECT" style="width: 100%;">
              <CitySelect v-model="formData[item.areaIdField]" v-model:provinceId="formData[item.provinceIdField]"
                v-model:provinceName="formData[item.provinceNameField]" v-model:cityId="formData[item.cityIdField]"
                v-model:cityName="formData[item.cityNameField]" v-model:areaId="formData[item.areaIdField]"
                v-model:areaName="formData[item.areaNameField]" @update:model-value="item.onChange"
                :disabled="item.config?.disabled || false" />
            </template>

            <el-input :style="getColumnWidth(item)" v-else-if="item.type === FORM_FIELD_TYPE.INPUT"
              v-model="formData[item.field]" @change="(v) => item.onChange && item.onChange(handlers, formData[item.field])"
              @update:modelValue="(v) => item.callback && item.callback(handlers, formData, v)" v-bind="item.props"
              :placeholder="item.placeholder" :type="item?.type === 'textarea' ? 'textarea' : 'text'"
              @click="formItemClick(item)" :disabled="item.config?.disabled || false">
              <template #suffix><span>{{ item.suffix ?? '' }}</span></template>
            </el-input>

            <el-input-number :style="getColumnWidth(item)" v-else-if="item.type === FORM_FIELD_TYPE.NUMBER"
              v-model="formData[item.field]" v-bind="item.props" :placeholder="item.placeholder"
              :controls-position="item.config && item.config.controlsPosition || 'right'"
              :max="item.config && item.config.max || ''" :min="item.config && item.config.min || ''"
              :precision="item.config && item.config.precision || ''" :step="item.config && item.config.step || ''"
              @click="formItemClick(item)" :disabled="item.config?.disabled || false" />

            <el-input :style="getColumnWidth(item)" v-else-if="item.type === FORM_FIELD_TYPE.TEXTAREA"
              v-model="formData[item.field]" v-bind="item.props" :placeholder="item.placeholder" type="textarea"
              @click="formItemClick(item)" :disabled="item.config?.disabled || false" />


            <el-switch :style="getColumnWidth(item)" v-else-if="item.type === FORM_FIELD_TYPE.SWITCH"
              v-model="formData[item.field]" :active-value="1" :inactive-value="0" v-bind="item.props" />

            <el-checkbox :style="getColumnWidth(item)" v-else-if="item.type === FORM_FIELD_TYPE.CHECKBOX"
              v-model="formData[item.field]" v-bind="item.props" />

            <el-checkbox-group v-else-if="item.type === FORM_FIELD_TYPE.CHECKBOX_GROUP" v-model="formData[item.field]">
              <el-checkbox :key="item.value" v-for="item in item.config.options" :label="item.label"
                :value="item.value" />
            </el-checkbox-group>


            <el-radio-group v-model="formData[item.field]" v-else-if="item.type === FORM_FIELD_TYPE.RADIO">
              <el-radio :key="item.value" v-for="item1 in item.config.options"
                :value="item1[item.config?.value ? item.config?.value : 'value']">
                {{ item1[item.config?.label || 'label'] }}
              </el-radio>
            </el-radio-group>



            <el-date-picker :style="getColumnWidth(item)" v-else-if="item.type === FORM_FIELD_TYPE.DATE"
              format="YYYY-MM-DD" :value-format="item.config && item.config.valueFormat || 'YYYY-MM-DD'"
              v-model="formData[item.field]" :type="item.type" v-bind="item.props" />


            <div :style="getColumnWidth(item)" v-else-if="item.type === FORM_FIELD_TYPE.DATETIME">
              <el-date-picker style="width: 100%"
                :value-format="item.config && item.config.valueFormat || 'YYYY-MM-DD HH:mm:ss'"
                @update:modelValue="(v) => item.callback(handlers, formData, v)" v-model="formData[item.field]"
                :type="item.type" v-bind="item.props" />
            </div>
            <div :style="getColumnWidth(item)" v-else-if="item.type === FORM_FIELD_TYPE.TIME">
              <el-time-picker style="width: 100%" v-model="formData[item.field]" placeholder="选择时间" v-bind="item.props"
                :value-format="item.config && item.config.valueFormat || 'HH:mm:ss'" />
            </div>
            <div :style="getColumnWidth(item)" v-else-if="item.type === FORM_FIELD_TYPE.TIMES">
              <el-time-picker style="width: 100%" v-model="formData[item.field]" placeholder="选择时间" v-bind="item.props"
                :value-format="item.config && item.config.valueFormat || 'HH:mm'" />
            </div>
            <div :style="getColumnWidth(item)" v-else-if="item.type === FORM_FIELD_TYPE.DATE_RANGE">
              <el-date-picker style="width: 100%;"
                :value-format="item.config && item.config.valueFormat || 'YYYY-MM-DD HH:mm:ss'"
                v-model="formData[item.field]" :type="item.type" range-separator="至" start-placeholder="开始日期"
                value-format="YYYY-MM-DD" end-placeholder="结束日期" v-bind="item.props" />
            </div>

            <div :style="getColumnWidth(item)" v-else-if="item.type === FORM_FIELD_TYPE.DATE_TIME_RANGE">
              <el-date-picker style="width: 100%;"
                :value-format="item.config && item.config.valueFormat || 'YYYY-MM-DD HH:mm:ss'"
                v-model="formData[item.field]" :type="item.type" range-separator="至" start-placeholder="开始日期"
                value-format="YYYY-MM-DD" end-placeholder="结束日期" v-bind="item.props" />
            </div>



            <CommonSelect v-else-if="item.type === FORM_FIELD_TYPE.SELECT" :config="item.config"
              :style="getColumnWidth(item)" :placeholder="item.placeholder" v-model="formData[item.field]" />



            <SingleLayerSelect v-else-if="item.type === FORM_FIELD_TYPE.SINGLE_LAYER_SELECT" :options="item.options"
              :disabled="item.disabled" v-model="formData[item.field]"
              @update:model-value="(v) => handleSelectChange(v, item)" />

            <EditableSelect v-else-if="item.type === FORM_FIELD_TYPE.EDITABLE_SELECT" :options="item.options"
              :type="item.inputType" :disabled="item.disabled" :input-props="item.inputProps"
              v-model="formData[item.field]" />

            <CommonTree :config="item.config" v-else-if="item.type === FORM_FIELD_TYPE.TREE"
              v-model="formData[item.field]" />

            <DynamicCascaderSelect v-else-if="item.type === FORM_FIELD_TYPE.DYNAMIC_CASCADER_SELECT"
              v-model:serialNum="formData[item.serialNumField]" v-model:serialName="formData[item.serialNameField]"
              v-model:serialType="formData[item.serialTypeField]" @change="(obj) => item.onChange(obj)"
              :disabled="item.config?.disabled || false" />
            <upload-basic v-model="formData[item.field]" :config="item.config"
              v-else-if="item.type === FORM_FIELD_TYPE.UPLOAD" @update:model-value="(v) => baseForm.validate()"
              @update:file-name="(v) => handleUpdateFileName(v, item.fileNameField)"
              :disabled="item.config?.disabled || false" />

            <template v-else-if="item.type === FORM_FIELD_TYPE.IMG && formData[item.field] !== ''">
              <el-image v-for="(imageUrl, index) in formData[item.field].split(',')" :key="index" :src="imageUrl"
                style="width: 100px; margin-right: 5px;" :disabled="item.config?.disabled || false" />
            </template>

            <ElButton type="primary" v-else-if="item.type === FORM_FIELD_TYPE.UPLOAD_IMPORT"
              @click="() => uploadImport(item.config)">
              导入</ElButton>
            <div v-else-if="item.type === FORM_FIELD_TYPE.EDITOR" style="height: 500px">
              <toolbar v-if="editorRef && editorRef[item.field]" :editor="editorRef[item.field]"
                style="border-bottom: 1px solid var(--el-border-color)" />
              <editor v-model="formData[item.field]" class="wang-editor-content" :default-config="editorConfig"
                @on-created="handleCreated($event, item)" />
            </div>

            <div v-else-if="item.type === FORM_FIELD_TYPE.INPUTNUMBER">
              <el-input-number v-model="formData[item.field]"
                @update:modelValue="(v) => item.callback && item.callback(handlers, formData, v)"
                :min="item.config?.min || item.config?.min == 0 ? item.config?.min : -999999"
                :max="item.config?.max ? item.config?.max : 10000000000"
                :step="item.config?.step ? item.config?.step : 1"
                :controls-position="item.config?.position ? 'right' : ''" />
            </div>

          </el-form-item>

          <div style="display: flex; justify-content: center;" v-if="item.type === FORM_FIELD_TYPE.TABLE">
            <div style="width: 800px">
              <BaseTable v-model="item.modelData" />
            </div>
          </div>
          <EditableTable :model-data="item.modelData" v-model="formData[item.field]"
            v-if="item.type === FORM_FIELD_TYPE.EDITABLETABLE" ref="tableRef"/>
        </template>
      </div>
    </el-form>
    <div style="padding-top: 20px;text-align: right" v-if="!(modelValue.hideButton == true)">

      <el-button @click="item['click'](item)" v-for="item in modelValue.buttons">{{ item.name }}</el-button>
      <el-button type="primary" @click="handleSave" :icon="Search"
        v-if="props.modelValue.save !== undefined ? props.modelValue.save : true">保存</el-button>
      <el-button @click="handleClose" :icon="Refresh">关闭</el-button>
    </div>
  </div>

</template>

<script setup>
import { Search, Sort, Refresh } from '@element-plus/icons-vue'
import FORM_FIELD_TYPE from '/@/constants/FormFieldType'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import '@wangeditor/editor/dist/css/style.css'
import { TypeUtils } from "/@/utils/TypeUtils";
import { useUserStore } from "/@/store/modules/user";
import VDialog from '/@/utils/dialogUtil.ts'
const baseForm = ref(null)
const tableRef = useTemplateRef("tableRef")
const props = defineProps({
  modelValue: {
    type: Object,
    required: true
  }
})
const columnCount = props.modelValue.columnCount || '6'
const columnWidth = props.modelValue.columnWidth || '300px'
const emits = defineEmits(['search', 'save', 'update:modelValue', 'callback', 'close'])
const formData = ref({});

const userStore = useUserStore()
const { token } = userStore
const editorConfig = reactive({
  placeholder: '请输入内容...',
  MENU_CONF: {
    uploadImage: {
      server: `${import.meta.env.VITE_APP_BASE_URL}/qiniu/fileupload2`, // 您的服务器地址，注意：当前接口格式特殊与其他vab接口不同，请查看vip文档
      fieldName: 'file',
      allowedFileTypes: ['image/*'],
      headers: {
        token: token
      }, // 如需传递token请写到在这里
      customInsert(res, insertFn) {
        if (res.success) {
          let url = res.data
          insertFn(url, '')
        }
      }
    },
  },
})
const rules = ref({})

// 适配动态生成表单时的表单校验规则处理
watch(() => props.modelValue.items, () => {
  for (let item of props.modelValue.items) {
    if (item.rule !== undefined) {
      if (TypeUtils.isArray(item.rule)) {
        rules.value[item.field] = item.rule
      } else {
        rules.value[item.field] = [item.rule]
      }
    }
  }
}, { immediate: true })

const finallyColumns = computed(() => {
  console.log("items", props.modelValue.items)
  const finallyitems = props.modelValue.items.filter(value => (value.isShow == undefined || value.isShow(formData.value) == true) && (value.hide == undefined || value.hide != true))
  console.log("finallyItems", finallyitems)
  return finallyitems
})

const editorRef = ref({})
const handleCreated = (editor, item) => {
  editorRef.value[item.field] = editor
}
const getColumnWidth = ((item) => {

  let width = item.width ? item.width : undefined;
  if (!width) {
    width = '100%'
    if (item.fullWidth === false) {
      if (item.type === FORM_FIELD_TYPE.INPUT) {
        width = '600px'
      }
      else if (item.type === FORM_FIELD_TYPE.NUMBER) {
        width = '600px'
      } else if (item.type === FORM_FIELD_TYPE.SELECT) {
        width = '600px'
      } else if (item.type === FORM_FIELD_TYPE.CHECKBOX_GROUP) {
        width = '600px'
      } else if (item.type === FORM_FIELD_TYPE.DATE_RANGE) {
        width = '600px'
      } else if (item.type === FORM_FIELD_TYPE.DATE_TIME_RANGE || item.type === FORM_FIELD_TYPE.TABLE) {
        width = '600px'
      }
    }

  }

  return { width: width }
})

const handlers = {
  updateParam(key, value) {
    formData.value[key] = value
  },
  hideItem(key, hide) {
    props.modelValue.items.filter(item => item.field == key).map((item) => {
      item.hide = hide
    })
  }
}

const handleUpdateFileName = (v, field) => {
  formData.value[field] = v
}
const handleClose = () => {
  emits('close')
}
const handleSelectChange = (v, item) => {
  if (item.callback) {
    item.callback(handlers, v, formData.value)
  }
}
// 搜索按钮事件
const handleSave = () => {
  console.log("current form data", formData.value)

  baseForm.value?.validate(async (valid) => {
    console.log(valid);
    if (valid) {
      
      // 处理可编辑表格的表单保存校验，支持多个可编辑表格
      const result = tableRef.value && (await Promise.all(tableRef.value.map(x=>{
          return new Promise((innerResolve,_)=>{
            x.validate(
              v=>{
                if (v) {
                  innerResolve(true) 
                } else {
                  innerResolve(false)
                }
              }
            )
          })
        })))

      const tableValidate =  result && result.filter(y=>!y).length === 0
      if (tableValidate === false) return
      //   emits('save', formData.value) //触发父类事件
      if (props.modelValue.callback) {
        console.log("formData value", formData.value)
        const items = props.modelValue.items.filter(x => x.noSend)
        const excludeField = items.map(x => x.field)
        let baseFormKey = Object.keys(formData.value).filter(x => !excludeField.includes(x));
        // 显示字符信息的字段要去除掉
        let labelField = props.modelValue.items.filter((item) => item.labelField).map(item => item.labelField);
        if (labelField.length == 0) {

          props.modelValue.callback(JSON.parse(JSON.stringify(formData.value)));
        } else {

          let result = {}
          for (let key of baseFormKey) {
            if (!labelField.includes(key)) {
              result[key] = formData.value[key]
            }
          }

          // 配置项只读数据绑定到表单数据中
          for (const item of props.modelValue.items.filter(x => x.type === FORM_FIELD_TYPE.READONLY)) {
            result[item.field] = item.value
          }
          props.modelValue.callback(result);
        }


      }
    }
  })

};

const uploadImport = (config) => {
  VDialog.open({
    title: '数据导入',
    content: { //内容初始形式
      type: 'component', //text:"",预留文本
      name: '/AttachmentUpload',
      // query: { companyInfoId: row.id },
    },
    config,
    callBack: (data) => {
      handlers.refresh()
      console.log("refresh", handlers.refresh)
      // handlers.refresh()
      console.log("upload recived data:", data)
    },
    onClose: () => {
      console.log("对话框已关闭");
    },
  })
}



const initData = (data) => {
  let fieldList = props.modelValue.items.map(value => value.field);

  // 没有初始化的对象使用配置的默认值填充
  if (Object.keys(data).length === 0) {
    props.modelValue.items.forEach(item => {
      console.log("defaultValue: ", "key", item.field, item.defaultValue)
      if (item.defaultValue !== undefined && formData.value[item.field] === undefined) {
        formData.value[item.field] = item.defaultValue
      }
    })
  }

  for (let key of Object.keys(data)) {
    formData.value[key] = data[key]
    if (data[key] == null && fieldList.indexOf(key) !== -1) {
      let item = props.modelValue.items.filter(value => value.field == key)
      if (item) {
        let target = item[0]
        if (target && target.config && target.config.defaultValue != undefined) {
          formData.value[key] = target.config.defaultValue
        }
      }
    }
  }


  for (let field of props.modelValue.items) {
    // 设置了多选初始化时逗号分隔
    if (field.multiple && data[field.field] !== undefined) {
      formData.value[field.field] = data[field.field].split(",")
    }
    if (field.type === FORM_FIELD_TYPE.SWITCH) {
      console.log(field);
      if (formData.value[field.field] == null) {
        formData.value[field.field] = 0
      }
    }
  }

}


watch(() => props.modelValue.modelData, (data) => {
  console.log("props modelValue modelData", props.modelValue.modelData)
  initData(data)
  console.log('current form data', formData.value)
}, { deep: true });

// 适配动态添加表单情况下的默认值
watch(() => props.modelValue.items, () => {
  initData({})
}, { deep: true });

initData(props.modelValue.modelData)
// 重置按钮事件
const handleReset = () => {
  props.modelValue.items.forEach((item) => {
    if (item.type === FORM_FIELD_TYPE.SELECT) {
      formData.value[item.field] = [];
    } else {
      formData.value[item.field] = item.defaultValue || null;
    }
  });
};


const formItemClick = (item) => {
  if (props.modelValue && props.modelValue.formItemClick) {
    props.modelValue.formItemClick(item)
  }
}
</script>

<style scoped>
.search-items {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  overflow: auto;
}

.form-item {
  /* 每个表单项的默认样式 */
}





/* 当没有autoFit且指定了列数时，保持grid列数不变 */
.search-items {
  display: grid;
  gap: 8px 16px;
  grid-template-columns: repeat(v-bind(columnCount), 1fr);
  /* 固定列数 */
}

.search-items.auto-fit {
  display: grid;
  gap: 8px 16px;
  grid-template-columns: repeat(auto-fill, minmax(v-bind(columnWidth), 1fr));
  /* 自适应列数 */
}

.expand-column {
  grid-column-start: 1;
  grid-column-end: v-bind(columnCount + 1);
}

:deep(.el-divider__text) {
  font-size: 23px;
  font-weight: 800;
  color: var(--el-color-primary);
}

/* 隐藏第三行之后的元素 */
.search-items:nth-child(n + 10) {
  display: none;
}


::v-deep(.el-form-item--default) {
  margin-bottom: 0;
}

::v-deep(.is-fullscreen) {
  color: red;
}
</style>
